home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#46 (Jul 89)
/
Terminal
/
SerI⁄O.asm
next >
Wrap
Assembly Source File
|
1989-03-09
|
7KB
|
220 lines
; File: SerI/O.asm
;----------------------------------------------------------------------
; SerI/O.asm consists of the following stand-alone serial I/O routines:
;
; Function OpenSerial(Port: integer): OSErr
; Function Config(Port, SerVal: integer): OSErr
; Function GetSerial(Port: integer, buffer: pointer): CharCnt
; Function PutSerial(Port: integer, CharBuf: pointer, count: longint): OSErr
; Function SetBuf(Port: integer, BufSiz: long): OSErr
;
; Port refers to the port reference number, which is -6 for the modem
; input port (port A) or -8 for printer input port (port B)
;
; For a great description of how to write modular assembly language
; routines see Dan Weston's "The Complete Book of Macintosh Assembly
; Language Programming Volume I", Appendix D
;
; 1/14/88 Working version of the routines
;
; written by Frank Henriquez
;----------------------------------------------------------------------
; Register usage:
; d0: general purpose.
; d1, d2, d3, d4, d5, d6, d7 : not used.
;
; a0: general purpose, used for buffers and parameter blocks.
; a1: general purpose.
; a2, a3, a4: not used.
; a6: used as the local stack frame pointer
; a5, a7 : system use.
;----------------------------------------------------------------------
Include Traps.D
Include SysEqu.D
XDEF OpenSerial
XDEF Config
XDEF GetSerial
XDEF PutSerial
XDEF SetBuf
; equates for each stack frame
pBlock equ -ioQelSize
OpenPar equ 2 ; OpenSerial - # of parameter words on stack
OpenRes equ 10 ; OpenSerial - offset to result word
OpenPort equ 8 ; OpenSerial - offset to Port Reference #
ConfPar equ 4 ; Config - # of parameter words on stack
ConfRes equ 12 ; Config - offset to result word
ConfPort equ 10 ; Config - offset to port Reference #
ConfVal equ 8 ; Config - offset to port config value
GetPar equ 6 ; you've probably figured the pattern
GetCnt equ 14 ; offset to character count
GetPort equ 12 ; out by now...
GetBuf equ 8 ; offset to character buffer pointer
PutPar equ 10
PutPort equ 16
PutBuf equ 12 ; offset to character buffer pointer
PutCnt equ 8 ; offset to character count pointer
PutRes equ 18 ; dummy result
SetPar equ 6
SetRes equ 14 ; offset to SetBuf result word
SetPort equ 12
SetSiz equ 8 ; offset to new buffer size
; misc. equates
SerReset equ 8 ; from Inside Macintosh
SerSetBuf equ 9 ; from Inside Macintosh
ioNamePtr equ 18 ; missing from MDS
;-------------- OpenSerial ------------------
; Opens the modem port for reads and writes.
;
; Procedure OpenSerial(Port: integer): OSErr
OpenSerial
link a6,#pBlock ; local space for parameter block
lea pBlock(a6),a0 ; point to parameter block
lea '.AIn',a1 ; assume port A input
cmpi.w #-6,OpenPort(a6) ; open port B if not -6 (port A)
beq.s @1
lea '.Bin',a1 ; open port B input
@1 bsr.s Openit
lea '.AOut',a1 ; assume port A output
cmpi.w #-6,OpenPort(a6)
beq.s @2
lea '.Bout',a1 ; open port B output
@2 bsr.s Openit
OExit move.w d0,OpenRes(a6) ; procedure returns a 0 if no errors
_KillIO ; kill any pending calls
unlk a6 ; discard local stack area
move.l (sp)+,a0 ; get return address
addq.l #OpenPar,sp ; clean up stack
jmp (a0) ; end of InitSerial
Openit
move.l a1,ioNamePtr(a0) ; tell the Device Manager which
_Open ; port to open
rts
;----------- Configure ports --------------
; Sets the Port to the baud rate, data length,
; parity, stops, etc. held in SerVal.
;
; Procedure Config(Port, SerVal : integer) : OSErr
Config
link a6,#pBlock ; local space for parameter block
lea pBlock(a6),a0 ; point to parameter block
move.w ConfPort(a6),d0 ; get Input Reference number
bsr.s doConf ; configure the input side
tst.w d0 ; check for errors and
bne.s CExit ; exit with the error flag in d0
move.w ConfPort(a6),d0 ; get Input Ref number
subq.w #1,d0 ; and make it the output ref num
bsr.s doConf ; configure the output side
CExit move.w d0,ConfRes(a6) ; save result
unlk a6
move.l (sp)+,a0
addq.l #ConfPar,sp ; and clean up the stack
jmp (a0) ; end of Configure
doConf move.w d0,ioRefNum(a0) ; port #
move.w #SerReset,csCode(a0) ; reset port to
move.w ConfVal(a6),csParam(a0) ; these new settings
_Control
rts
;---------------- SetBuf -------------------
; increases the size of the Port input buffer
;
; SetBuf(Port:Integer, BufSiz:long):OSErr
SetBuf link a6,#pBlock ; local space for parameter block
move.l SetSiz(a6),d0
beq.s @1 ; if size = 0, reset input buffer
_NewPtr ; get a nonrelocatable block
tst.l d0 ; abort if couldn't get it
bne Exit
move.l a0,a1 ; save block ptr in a1
move.l SetSiz(a6),d0 ; reload the buffer size
@1 lea pBlock(a6),a0 ; point to parameter block
move.w SetPort(a6),ioRefNum(a0)
move.w #SerSetBuf,csCode(a0)
move.l a1,csParam(a0) ; pointer to new buffer
move.w d0,csParam+4(a0)
_Control
Exit move.w d0,SetRes(a6)
unlk a6 ; standard exit routine
move.l (sp)+,a0
addq.l #SetPar,sp
jmp (a0) ; end of SetBuf
;--------------- GetSerial ----------------
; GetSerial checks the Port to see if any
; characters have been received, and proceeds
; to read them into the input buffer.
; If none have been received, GetSerial returns
; a 0 in the character count variable.
;
; Procedure GetSerial(Port:integer, buffer:pointer) : CharCnt: long
GetSerial
link a6,#pBlock
lea pBlock(a6),a0
move.w GetPort(a6),ioRefNum(a0)
move.w #2,csCode(a0) ; call SerGetBuf
_Status
move.l csParam(a0),d0 ; get # of characters received
move.l d0,GetCnt(a6)
beq.s @2 ; if none, then leave, if there are
; characters available, read them.
@1 move.w GetPort(a6),ioRefNum(a0)
move.l GetBuf(a6),ioBuffer(a0) ; the input buffer
move.l d0,ioReqCount(a0) ; read the characters
_Read
@2 unlk a6 ; standard exit routine
move.l (sp)+,a0
addq.l #GetPar,sp ; leave char count on stack
jmp (a0) ; end of GetSerial
;--------------- PutSerial ----------------
; PutSerial sends the characters in the buffer
; out the Port. This routine is pretty
; primitive - it ignores any pending writes
; and errors, but...it works. It returns a dummy result.
;
; function PutSerial(Port:integer, CharBuf:pointer, count: pointer): OSErr
PutSerial
link a6,#pBlock ; local space for parameter block
lea pBlock(a6),a0 ; point to parameter block
move.w PutPort(a6),d0 ; get the port ref #
subq.w #1,d0 ; make it the port output ref num
move.w d0,ioRefNum(a0) ; modem output port
move.l PutBuf(a6),ioBuffer(a0) ; point to buffer
move.l PutCnt(a6),a1 ; get pointer to char count
move.l (a1),ioReqCount(a0) ; and put char count here
_Write
move.w #0,PutRes(a6) ; save a 0 as a dummy result
unlk a6 ; standard exit routine
move.l (sp)+,a0
adda.l #PutPar,sp
jmp (a0) ; end of PutSerial